#include "Image.h"
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;
static Image::Piexl LerpPiexl(Image::Piexl p1, Image::Piexl p2, float lerp);

Image::Image(string path)
{
	Mat img = imread(path);
	width = img.cols;
	height = img.rows;
	dataPtr = new Piexl[width * height];
	for (size_t y = 0; y < height; y++)
	{
		for (size_t x = 0; x < width; x++)
		{
			Vec3b intensity = img.at<Vec3b>(y, x);
			dataPtr[y * width + x] = { intensity.val[2], intensity.val[1], intensity.val[0] };
		}
	}
}

Image::~Image()
{
	delete[] dataPtr;
}

Image::Piexl Image::GetPiexl(int x, int y)
{
	return dataPtr[x + y * width];
}

void Image::SetPiexl(int x, int y, Piexl piexl)
{
	dataPtr[x + y * width] = piexl;
}

void Image::Resize(int width, int height)
{
	Piexl* newBuffer = new Piexl[width * height];
	float scaleX = this->width / (float)width;
	float scaleY = this->height / (float)height;

	for (size_t x = 0; x < width; x++)
	{
		float srcX = (x + 0.5f) * scaleX - 0.5f;
		int lx = (int)srcX;
		float kx = srcX - lx;

		for (size_t y = 0; y < height; y++)
		{
			float srcY = (y + 0.5f) * scaleY - 0.5f;
			int ly = (int)srcY;
			float ky = srcY - ly;

			Piexl p1 = GetPiexl(lx, ly);
			Piexl p2 = GetPiexl(lx, ly + 1);
			Piexl p3 = GetPiexl(lx + 1, ly);
			Piexl p4 = GetPiexl(lx + 1, ly + 1);

			newBuffer[x + y * height] = LerpPiexl(
				LerpPiexl(p1, p2, ky),
				LerpPiexl(p2, p3, ky),
				kx
			);
		}
	}

	delete[] this->dataPtr;
	this->dataPtr = newBuffer;
	this->width = width;
	this->height = height;
}

void Image::Show(string title)
{
	Mat mat = Mat::zeros(width, height, CV_8UC3);
	for (size_t x = 0; x < width; x++)
	{
		for (size_t y = 0; y < height; y++)
		{
			Piexl p = GetPiexl(x, y);
			mat.at<Vec3b>(y, x) = { p.blue,p.green,p.red };
		}
	}
	imshow(title, mat);
}

static Image::Piexl LerpPiexl(Image::Piexl p1, Image::Piexl p2, float lerp) {
	Image::Piexl res =
	{
		((p1.red - p2.red) * lerp + p2.red),
		((p1.green - p2.green) * lerp + p2.green),
		((p1.blue - p2.blue) * lerp + p2.blue)
	};
	return res;
}